//深拷贝
//map处理循环引用问题 objA = {} ObjB = {a: objA} objeA.b = objB 进入无限递归
// 会处理 Date RegExp Map Set Symbols
//  Symbols属性不可枚举 Object.keys 和 for in 不能访问到，需要特殊处理(在map中Symbols)
//注意事项：
// 1、函数拷贝： 函数是直接引用而不是深拷贝，因为函数拷贝没有实际意义且可能带来问题
// 2、DOM元素： 这个实现不处理DOM元素的拷贝，如果需要拷贝DOM元素，需要特殊处理
// 对于大型对象或频繁拷贝的场景，可能需要考虑性能优化
// 某些特殊对象如Error对象、Promise等可能需要额外处理

function deepCopy(target, map = new WeakMap()) {
  if (target === null || typeof target !== "object") return target;

  // 处理循环引用
  if (map.has(target)) {
    return map.get(target);
  }

  if (target instanceof Date) {
    return new Date(target);
  }

  if (target instanceof RegExp) {
    return new RegExp(target.source, target.flags);
  }

  if (target instanceof Map) {
    const clone = new Map();
    map.set(target, clone);
    target.forEach((value, key) => {
      clone.set(key, deepCopy(value, map));
    });
    return clone;
  }
  if (target instanceof Set) {
    const clone = new Set();
    map.set(target, clone);
    target.forEach((item) => {
      clone.add(deepCopy(item, map));
    });
    return clone;
  }
  // 处理数据和普通对象 Obejct.getPrototypeOf 等价于 target.__proto__
  const clone = Array.isArray(target)
    ? []
    : Object.create(Object.getPrototypeOf(target));
  map.set(target, clone);
  // 复制Symbol 属性
  const symKeys = Object.getOwnPropertySymbols(target);
  if (symKeys.length) {
    symKeys.forEach((symKey) => {
      clone[symKey] = deepCopy(target[symKey], map);
    });
  }
  for (const key in target) {
    if (Object.prototype.hasOwnProperty.call(target, key)) {
      clone[key] = deepCopy(target[key], map);
    }
  }
  return clone;
}

module.exports = {
  deepCopy,
};
